package com.lgrglw.search.dao;

import org.apache.commons.lang.StringUtils;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;

/**
 * 搜索工具类
 * 
 * @author liwei
 * 
 */
public class SearchTools {
	/**
	 * 将全角字符转化为半角字符
	 * 
	 * @param qjStr
	 * @return
	 */
	public final static String qj2bj(String qjStr) {
		char[] c = qjStr.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] == 12288) {
				c[i] = (char) 32;
				continue;
			}
			if (c[i] > 65280 && c[i] < 65375)
				c[i] = (char) (c[i] - 65248);
		}
		return new String(c);
	}

	/**
	 * 讲半角字符转化为全角字符
	 * 
	 * @param bjStr
	 * @return
	 */
	public final static String bj2qj(String bjStr) {
		char[] c = bjStr.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] == 32) {
				c[i] = (char) 12288;
				continue;
			}
			if (c[i] < 127)
				c[i] = (char) (c[i] + 65248);
		}
		return new String(c);
	}

	/**
	 * 生成相等的搜索条件，即 name="张三"这样的条件格式，即字段精确相等，才算符合条件
	 * 
	 * @param source
	 *            需要被追加的条件
	 * @param filed
	 *            字段在索引文件中的名称
	 * @param keyWord
	 *            条件
	 * @param type
	 *            符合条件的类型 1.一定要符合 0，一定不能符合 2可以符合也可以不符合
	 */
	public final static void buildQueryForTerm(BooleanQuery source,
			String filed, String keyWord, int type) {
		Query query = new TermQuery(new Term(filed, keyWord));
		switch (type) {
		case SearchContants.MUST:
			source.add(query, BooleanClause.Occur.MUST);
			break;
		case SearchContants.MUST_NOT:
			source.add(query, BooleanClause.Occur.MUST_NOT);
			break;
		case SearchContants.SHOULD:
			source.add(query, BooleanClause.Occur.SHOULD);
			break;
		}
	}

	/**
	 * 通配符条件查询
	 * 
	 * @param source
	 *            需要被追加的条件
	 * @param filed
	 *            字段在索引文件中的名称
	 * @param keyWord
	 *            条件，需要自己增加好通配符
	 * @param type
	 *            符合条件的类型 1.一定要符合 0，一定不能符合 2可以符合也可以不符合
	 */
	public final static void buildQueryForWildcard(BooleanQuery source,
			String filed, String keyWord, int type) {
		Query query = new WildcardQuery(new Term(filed, keyWord));
		switch (type) {
		case SearchContants.MUST:
			source.add(query, BooleanClause.Occur.MUST);
			break;
		case SearchContants.MUST_NOT:
			source.add(query, BooleanClause.Occur.MUST_NOT);
			break;
		case SearchContants.SHOULD:
			source.add(query, BooleanClause.Occur.SHOULD);
			break;
		}
	}
	/**
	 * 增加区间查询条件
	 * @param source 需要被追加的条件
	 * @param filed  字段在索引文件中的名称
	 * @param leftKey 前区间值
	 * @param rightKey  后区间值
	 * @param include 是否包含区间
	 * @param type 符合条件的类型 1.一定要符合 0，一定不能符合 2可以符合也可以不符合
	 */
	public final static void buildQueryRange(BooleanQuery source, String filed,
			String leftKey, String rightKey, boolean include, int type) {
		Query query = new RangeQuery(new Term(filed,leftKey),new Term(filed,rightKey),include);
		switch (type) {
		case SearchContants.MUST:
			source.add(query, BooleanClause.Occur.MUST);
			break;
		case SearchContants.MUST_NOT:
			source.add(query, BooleanClause.Occur.MUST_NOT);
			break;
		case SearchContants.SHOULD:
			source.add(query, BooleanClause.Occur.SHOULD);
			break;
		}
	}
	
	/**
     * 对输入的检索关键词进行相关的处理，以符合QueryParser的语句要求，过滤掉非法字符;</p>
     *  首先进行全角转换为半角，再删除不符合lucene保留字格式的相关字符。
     * @param queryString 查询语句
     * @return 转换后的字符串，如果输入的查询为空(null或者空格或者空字符串)，则返回""
     */
    public static String tranKeyWord(String queryString){
        if(StringUtils.isBlank(queryString)){
            return "";
        }
        queryString=SearchTools.qj2bj(queryString.trim());
        //把重复的"++"替换为"+"
        //把多个"+"删除
        queryString=queryString.replaceAll("\\+{1,}","");
        //把多个空格替换为一个
        queryString=queryString.replaceAll("\\s{2,}"," ");
        //把多个"-"替换为一个
        queryString=queryString.replaceAll("\\-{2,}","-");
        //替换掉"?"
        queryString=queryString.replaceAll("\\?","");
        return queryString;         
    }
    
}
